package apig.client.prof;

import java.util.*;

import org.gwm.client.impl.*;

import apig.client.*;
import apig.client.serviface.*;

import com.google.gwt.core.client.*;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.*;

public class StudInternalFrame extends DefaultGInternalFrame {

	private HorizontalPanel content;
	private StudView sv;
	private Student s;
	private MenuBar mb;
	private DiscTree dt;
	private Lab l;
	private int r;
	private TextBox tb = new TextBox();
	private VerticalPanel tableContainer;
	private CodeBrowseListener cbl;

	public StudInternalFrame(Student s, CodeBrowseListener cbl) {
		super(s.getFullName());
		this.s = s;
		this.cbl = cbl;
		sv = new StudView(s);

		initUi();
		setSize(800, 500);
	}

	private void initUi() {

		System.out.println("init internal frame");
		tb.setSize("30px", "100%");
		content = new HorizontalPanel();
		content.setWidth("100%");
		content.setHeight("100%");
		dt = new DiscTree();
		content.add(dt);
		content.setCellWidth(dt, "20%");
		content.setCellHeight(dt, "100%");
		dt.setHeight("100%");
		dt.setWidth("100%");
		VerticalPanel right = new VerticalPanel();
		content.add(right);
		right.setHeight("100%");
		right.setWidth("100%");
		content.setCellWidth(right, "100%");
		content.setCellHeight(right, "100%");
		RevisionBar rb = new RevisionBar();
		right.add(rb);
		right.setBorderWidth(2);
		rb.setWidth("100%");
		rb.setHeight("100%");

		tableContainer = new VerticalPanel();
		tableContainer.setSize("100%", "100%");
		right.add(tableContainer);
		right.setCellWidth(tableContainer, "100%");
		right.setCellHeight(tableContainer, "100%");

		setContent(content);
	}

	private void setLab(Lab l) {
		this.r = 0;
		tb.setText("");
		this.l = l;
		reloadCodes();
	}

	private void setRevision(int r) {
		if (l == null) {
			return;
		}
		this.r = r;
		reloadCodes();
	}

	private void reloadCodes() {
		CodeQuery cq = new CodeQuery();
		cq.labId = l.labId;
		cq.ownerId = s.id;
		cq.revision = r == 0 ? Integer.MAX_VALUE : r;
		Stubman.getStubman().getService()
				.getCodes(cq, new AsyncCallback<List<Code>>() {
					@Override
					public void onFailure(Throwable caught) {
						System.out.println("fail: " + caught);
					}

					@Override
					public void onSuccess(List<Code> result) {
						onCodesGotten(result);
					}
				});
	}
	
	private String format(double d) {
		return ((int) d) + "." + ((int)((d - ((int) d))*100));
	}

	private void onCodesGotten(List<Code> result) {
		CellTable<Code> table = new CellTable<Code>();
		TextColumn<Code> nameCol = new TextColumn<Code>() {
			@Override
			public String getValue(Code c) {
				return c.name;
			}
		};
		TextColumn<Code> revCol = new TextColumn<Code>() {
			@Override
			public String getValue(Code c) {
				return Integer.toString(c.revision);
			}
		};
		TextColumn<Code> checkedCol = new TextColumn<Code>() {
			@Override
			public String getValue(Code c) {
				if (c.checked) {
					return "+";
				} else {
					return "-";
				}
			}
		};
		TextColumn<Code> veraCol = new TextColumn<Code>() {
			@Override
			public String getValue(Code c) {
				return format(c.veracity) + "/" + c.hypoCount;
			}
		};
		table.addColumn(nameCol, "Имя файла");
		table.addColumn(revCol, "Ревизия");
		table.addColumn(checkedCol, "Проверено");
		table.addColumn(veraCol, "Алерты");
		table.setRowData(0, result);
		table.addCellPreviewHandler(new com.google.gwt.view.client.CellPreviewEvent.Handler<Code>() {
			long lastClick = -1000;
			@Override
			public void onCellPreview(CellPreviewEvent<Code> event) {
				long clictAt = System.currentTimeMillis();
				if (event.getNativeEvent().getType().contains("click")) {
					if (clictAt - lastClick < 300) { 
						onCodeSelected(event.getValue());
					}
					lastClick = System.currentTimeMillis();
				}
			}
		});
		table.setRowCount(result.size(), true);
		tableContainer.clear();
		tableContainer.add(table);
		table.setWidth("100%");
		table.setHeight("100%");
		tableContainer.setCellHeight(table, "100%");
		tableContainer.setCellWidth(table, "100%");
	}
	
	private void onCodeSelected(Code c) {
		cbl.browseCode(c);
	}

	private class LabTreeItem extends Button {

		private Discipline d;
		private Lab l;

		public LabTreeItem(Discipline d, Lab l) {
			super(l.labName);
			this.d = d;
			this.l = l;

			setTitle(l.labName);
			addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					setLab(LabTreeItem.this.l);
				}
			});
		}
	}

	private class RevisionBar extends HorizontalPanel {

		public RevisionBar() {
			setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
			Label rl = new Label("Ревизия");
			Button ok = new Button("Ok");
			HorizontalPanel stub = new HorizontalPanel();
			stub.setWidth("100%");
			stub.setHeight("100%");
			add(rl);
			add(tb);
			add(ok);
			add(stub);
			setCellWidth(stub, "100%");
			setCellHeight(stub, "100%");
			ok.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					String text = tb.getText();
					int i = -1;
					try {
						i = Integer.parseInt(text);
					} catch (Exception ex) {
					}
					if (i > 0) {
						setRevision(i);
					}
				}
			});
		}
	}

	private class DiscTree extends Tree {

		private TreeItem root;
		private HashMap<Discipline, List<Lab>> oldResult;

		public DiscTree() {

			setAnimationEnabled(true);
			reloadTree();
			Timer t = new Timer() {
				public void run() {
					// reloadTree();
					schedule(Stubman.TIMER_DELAY);
				}
			};
			t.schedule(Stubman.TIMER_DELAY);
		}

		private void onTreeDataCame(HashMap<Discipline, List<Lab>> result) {

			clear();
			root = new TreeItem("Предметы");
			root.setState(true);
			addItem(root);
			for (Discipline d : result.keySet()) {
				TreeItem dItem = new TreeItem(d.name);
				dItem.setState(true);
				root.addItem(dItem);
				for (Lab l : result.get(d)) {
					dItem.addItem(new LabTreeItem(d, l));
				}
			}
		}

		private void reloadTree() {
			Stubman.getStubman()
					.getService()
					.getStudLabs(
							s.id,
							new AsyncCallback<HashMap<Discipline, List<Lab>>>() {

								@Override
								public void onSuccess(
										HashMap<Discipline, List<Lab>> result) {
									onTreeDataCame(result);
								}

								@Override
								public void onFailure(Throwable caught) {
									System.out.println("fail: "
											+ caught.getMessage());
								}
							});
		}
	}
}
